﻿package edu.pku.se.chocolate.solver;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.util.Log;
import edu.pku.se.chocolate.datastructure.Category;
import edu.pku.se.chocolate.datastructure.Message;
import edu.pku.se.chocolate.datastructure.MessageNumberResponse;
import edu.pku.se.chocolate.datastructure.RequstMessageResponse;
import edu.pku.se.chocolate.datastructure.Tag;
/**
 * ChocolateSolver
 * @author Jas0n
 *	此类为单例类
 */
public class ChocolateSolver {
	public static final int PAGE_ITEM_NUM = 20;
	public static final String PREFERENCE_NAME = "SaveSetting"; 
	public static final int PREFERENCE_MODE = Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE;
	public static final String[] SERVER_ADDRESS = new String[]{"http://chocolate.seemsfunny.com/chocolate/","http://162.105.16.238:8080/chocolate/"};
	ArrayList<Category> categoryList;
	Activity activity;
	Storage storage;
	
	Handler autoReflashHandler ;
	ArrayList<Tag> autoReflashTags;
	
	Handler msgGotHandler;
	
	int lastmessageid;
	Handler msgNumGotHandler;
	
	static ChocolateSolver solver;
	
	/**
	 * 获取ChocolateSolver 的实例,
	 * @return
	 */
	public static ChocolateSolver getInstance(){	
		return solver;
	}
	/**
	 * 第一次调用getInstance之前需要先初始化实例
	 * @param act
	 */
	public static void InitChocolateSolver(Activity act){
		if (solver == null){
			solver = new ChocolateSolver(act);
		}		
	}
	/**
	 * 私有构造器
	 * 
	 * @param activity
	 */
	private ChocolateSolver(Activity activity){
		this.activity = activity;
		storage = new Storage(this);
	}
	/**
	 * +获取大类列表 () : 分类
	 */
	public ArrayList<Category> getCategoryList(){
		if (categoryList == null){
			String[] ctgs_chs = new String[]{
				"二手","十大","讲座","演出","公告","征恋人","征玩友","校园活动","国际交流","失物招领","自定义类"
			};
			String[] ctgs_eng = new String[]{
				"secondhand","hottopic","lecture","show","notice","piebridge","piefriends","campusinfo","oir","lostfound","custom"	
			};
			categoryList = new ArrayList<Category>();
			SharedPreferences sp = activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE);
			for(int i = 0 ; i < ctgs_chs.length; i++){
				categoryList.add(new Category(ctgs_chs[i],ctgs_eng[i],sp.getBoolean(ctgs_eng[i], true)));
			}
		}
		return categoryList;
	}
	
	/**
	 * +设置分类显示与否 (in 分类 : 分类, in 显示与否 : bool)
	 */
	public boolean setIsCategoryShow(Category ctg,boolean isShow){
		ctg.isShown = isShow;
		Log.v("Solver","setIsCategoryShow:"+ctg.getDisplayName() + ":"+isShow);
		SharedPreferences sp =activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE); 
		SharedPreferences.Editor editor = sp.edit();
		editor.putBoolean(ctg.getStorageName(), isShow);
		return editor.commit();
	}
	/**
	 * +设置更新频率 (in 频率)
	 * 单位:秒
	 * 用0表示不自动刷新
	 */
	public boolean setRefleshFrequency(int freq){		
		if (freq == 0)
			FetchMessageNumberService.requestStop(activity);
		else 
			FetchMessageNumberService.submitTask(activity, null);
		SharedPreferences sp =activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE); 
		SharedPreferences.Editor editor = sp.edit();
		editor.putInt("RefleshFrequency", freq);		
		return editor.commit();
	}
	/**
	 * +获取更新频率 ()
	 * 单位:秒
	 * 用0表示不自动刷新
	 */
	public int getRefleshFrequency(){
		SharedPreferences sp = activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE);
		return sp.getInt("RefleshFrequency", 60);
	}

	/**
	 * +获取标签列表 (in 大类 : 分类) : 标签
	 */
	public ArrayList<Tag> getTagList(Category ctg){
		Log.v("getTagList",ctg.getStorageName());		
		return storage.getTagList(ctg.getStorageName());
	}
	/**
	 * 获取所有需要提醒更新的标签,在主界面中调用
	 */
	public ArrayList<Tag> getAllNotifyTag(){
		Log.v("getAllTag","---");		
		return storage.getAllNotifyTag();
	} 
	/**
	 * +获取最新消息 (in 标签 : 标签) : 消息
	 */
	public ArrayList<Message> getLatestMessages(Tag tag){
		Log.v("getLatestMessages","from tagID:"+tag.ID+"");
		ArrayList<Message> msgs = storage.getLatestMessages(tag.ID,tag.latest_msg_id,PAGE_ITEM_NUM);	
		if (!msgs.isEmpty())
			lastmessageid = msgs.get(msgs.size()-1).ID;
		else
			lastmessageid = -1;
		Log.v("getLatestMessages","return:"+msgs);
		return msgs;
	}
	/**
	 * +获取下一页消息 (in 当前标签 : 标签 , +ID)
	 * 获取pre_id之后的N条消息
	 */
	public ArrayList<Message> getNextPage(Tag tag){
		Log.v("getNextPage","at tag:"+tag.name+" from mid:"+lastmessageid);
		ArrayList<Message> msgs = storage.getNextNMessage(tag.ID,lastmessageid,PAGE_ITEM_NUM);		
		if (!msgs.isEmpty())
			lastmessageid = msgs.get(msgs.size()-1).ID;
		else
			lastmessageid = -1;
		Log.v("getNextPage","results:"+msgs);
		return msgs;
	}
	/**
	 * +获取更新数(in 标签 : 标签) : int
	 */
	public int getNewMessageNumber(Tag tag){		
		return storage.getNewMessageNumber(tag.ID);
	}
	/**
	 * 获取收藏页面中消息列表的第几页消息,
	 * @param PageNum :从0开计数
	 * @return 一页消息,如果该页的木有消息,返回才Arraylist的size为0,返回值不是null
	 */
	public ArrayList<Message> getFavouriteMessage(int PageNum){		
		return storage.getFavouriteMessage(PageNum*PAGE_ITEM_NUM,PAGE_ITEM_NUM);
	}
	
	/**
	 * +添加标签(in 标签 : 标签)
	 * @return  是否成功
	 */
	public boolean addTag(Tag tag){		
		Log.v("addTag..",tag.toString());
		return storage.addTag(tag);
	}
	/**
	 * +删除标签(in 标签 : 标签)
	 * @return 返回是否成功
	 */
	public boolean deleteTag(Tag tag){
		return storage.deleteTag(tag);
	}

	/**
	 * +收藏消息(in 消息 : 消息)
	 */
	public boolean collectMessage(Message msg){
		
		if (storage.collectMessage(msg.ID)){
			msg.favorite = 1;
			return true;
		} return false;
	}
	/**
	 * +取消收藏消息 (in 消息 : 消息)
	 */
	public boolean cancleCollectMessage(Message msg){
		if ( storage.cancleCollectMessage(msg.ID)){
			msg.favorite = 0;
			return true;
		} return false;
	}
	
	/**
	 * 获取以给定字符串preffix为前缀的左右版面的名字
	 * 最多10个.
	 * @param preffix 版面的前缀
	 * @return 返回结果数组,格式为"版面英文名/版面中文名"
	 */
	public ArrayList<String> getBBSforumName(String preffix){
		return storage.getBBSforumName(preffix.toLowerCase());
	}
	/**
	 * 
	 * @return BBS所有版面列表,格式为"版面英文名/版面中文名"
	 */
	public ArrayList<String> getBBSAllForumName(){
		return storage.getBBSAllforumName();
	}
	/**
	 * +设置需要自动刷新的(in 当前活动视图  : android.view.View)
	 * 自动刷新所用, 
	 * 	在消息界面的时候,应该设置为标签条带
	 * 	主界面的时候应该设置为大类列表条带
	 * 	其他界面应该设置为null
	 */
	public void setautoReflash(Handler handler,ArrayList<Tag> tags){
		Log.v("setautoReflash","tags::"+tags+"handler:"+handler);
//		if (handler == null){
//			Log.e("setautoReflash","handler is null!!");
//		}
		autoReflashHandler = handler;
		autoReflashTags = tags;
		//FetchMessageNumberService.submitTask(activity, tags);		
	}
	/**
	 * 获取自动更新所需的标签
	 * @return
	 */
	public ArrayList<Tag> getAutoReflashTags(){
		ArrayList<Tag> tags = new ArrayList<Tag>();
		if (autoReflashTags != null)
		for(Tag t : autoReflashTags){
			tags.add(storage.getTag(t.ID));
		}
		return tags;
	}
	/**
	 * 获取服务器地址
	 * @return
	 */
	public String getServerAddress(){
		return SERVER_ADDRESS[getServerAddressID()];
	}
	/**
	 * 获取服务器的编号
	 * @return
	 */
	public int getServerAddressID(){
		SharedPreferences sp = activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE);
		int id = sp.getInt("ServerAddressID", 0);
		return id;
	}
	/**
	 * 设置服务器
	 * @param id 1为校内服务器,0为校外服务器
	 * @return
	 */
	public boolean setServerAddress(int id){
		if (id != 0 && id != 1) return false;
		SharedPreferences sp =activity.getSharedPreferences(PREFERENCE_NAME, PREFERENCE_MODE); 
		SharedPreferences.Editor editor = sp.edit();
		editor.putInt("ServerAddressID", id);
		return editor.commit();
	}
	/**
	 * +刷新标签(in 标签 : 标签, in _____handler__________)
//	 */
//	public void refreshAllTag_no_use(final ArrayList<Tag> tags,final Tag tag,final Handler handler){		
//		FetchMessageNumberService.submitTask(activity, tags);
//		msgNumGotHandler = new Handler() {
//			@Override
//			public void handleMessage(android.os.Message msg) {
//				Tag t = storage.getTag(tag.ID);
//				requestNextPage(t , handler);
//				super.handleMessage(msg);
//			}
//		};
//		
//	}
	/**
	 * +请求最新消息 (in 标签 : 标签, in 源 : android.view.View)
	 */
	public void requestLatestMessage(final Tag tag, final Handler handler){	
		Log.v("requestNextPage", "hello");
		if (handler == null){
			Log.e("requestLatestMessage","handler is null");
		}
		FetchMessageNumberService.submitTask(activity,getAutoReflashTags());		
		msgNumGotHandler = new Handler() {
			@Override
			public void handleMessage(android.os.Message msg) {				
				Tag t = storage.getTag(tag.ID);
				Log.v("msgNumGotHandler","old TAG:"+tag);
				lastmessageid = t.latest_msg_id;
				Log.v("msgNumGotHandler","new TAG:"+t);
				requestNextPage(t, handler);
				msgNumGotHandler = null;
			}
		};
	}
	/**
	 * +请求下一页消息 (in 标签 : 标签)
	 * @param tag	当前页的标签
	 * @param handler 获取信息之后的通知对象
	 */
	public void requestNextPage(Tag tag,Handler handler){	
		if (handler == null){
			Log.e("requestNextPage","handler is null,abort");
			return;
		}
		Log.v("requestNextPage", "from id:"+ lastmessageid);
	
		FetchMessageService.submitTask(activity, tag, lastmessageid, PAGE_ITEM_NUM);
		msgGotHandler = handler;
	}
	
	/**
	 * 请求消息内容的数据结果的回调方法
	 * @param result
	 */
	public void setResponseMessage(RequstMessageResponse result){
		Log.v("setResponseMessage", "hello");
		//先存数据库
		Log.v("setResponseMessage", "Adding Message.....");
		Log.v("setResponseMessage", "result.tag: "+result.tag.toString());
		Log.v("setResponseMessage", "result.messages num: "+result.messages.size());
		Log.v("setResponseMessage", "result.messages: "+result.messages);
		storage.addMessage(result.tag,result.messages);
		if (msgGotHandler != null ){
			clearTagNewMsgNum(result.tag);
			if (!msgGotHandler.sendEmptyMessage(0)) 
				Log.e("setResponseMessage", "send Message error");
			msgGotHandler = null;
			Log.v("setResponseMessage","msgGotHandler:"+msgGotHandler);
		}		
	}
	
	/**
	 * 请求消息新数目的结果的回调方法
	 * @param result
	 */
	public void setResponseMessageNumber(ArrayList<MessageNumberResponse> result){
		Log.v("setResponseMessageNumber", "hello");
		//先存数据库
		for(MessageNumberResponse mnr : result){
			Log.v("setResponseMessageNumber","OLD:"+mnr.tag+"|||||new:newid->"+mnr.newestID+",newnum->"+mnr.newMessageNumber);
			Tag t = storage.getTag(mnr.tag.ID);
			if (t.latest_msg_id != mnr.newestID){
				t.new_msg_num += mnr.newMessageNumber;
				t.latest_msg_id = mnr.newestID;
			}
			if (!storage.updateTag(mnr.tag.ID,new String[]{Storage.C_TlatestestMID,Storage.C_Tnewmsgnum}
						, new String[]{""+mnr.newestID,""+t.new_msg_num})){
				Log.e("setResponseMessageNumber", "update Tag error");
			}
		}
		//处理得到数据后的事件
		if (msgNumGotHandler != null){
			Log.v("setResponseMessageNumber","msgNumGotHandler");
			if (!msgNumGotHandler.sendEmptyMessage(0)){
				Log.e("setResponseMessageNumber", "msgNumGotHandler failed");
			}
		} else if (autoReflashHandler != null){
			Log.v("setResponseMessageNumber","autoReflashHandler");
			if (!autoReflashHandler.sendEmptyMessage(0)){
				Log.e("setResponseMessageNumber", "autoReflashHandler failed");
			}
		} else {
			Log.e("setResponseMessageNumber", "NO handler???");
		}
	}
	public int getCategoryNewMessageNumber(Category category) {
		Log.v("getCategoryNewMessageNumber","category:"+category.getDisplayName());
		ArrayList<Tag> tagList = storage.getTagList(category.getStorageName());
		int ans = 0;
		for(Tag t:tagList){
			if (t.isNotify != 0){
				ans += t.new_msg_num;
			}
		}
		return ans;
	}
	/**
	 * 设置标签是否及时提醒
	 * @param tag
	 * @param isNotify
	 * @return
	 */
	public boolean setTagNotify(Tag tag,boolean isNotify){
		return storage.updateTag(tag.ID,new String[]{Storage.C_Tisnotify}
									, new String[]{""+isNotify});
	}
	/**
	 * 清空tag的最新消息数
	 * @param tag
	 * @return
	 */
	public boolean clearTagNewMsgNum(Tag tag){
		Log.v("clearTagNewMsgNum","at tag:"+tag);
		return storage.updateTag(tag.ID,new String[]{Storage.C_Tnewmsgnum}
									, new String[]{"0"});
	}
	/**
	 * 设置一条消息已读
	 * @return
	 */
	public boolean setMessageRead(Message msg){
		return storage.updateMessage(msg.ID,
				new String[]{Storage.C_Misread}, new String[]{"1"});
	}
}
